﻿using System;
using System.Collections;
using System.Reflection;


namespace RoughJs.Ast
{
    public abstract class VMBridge
    {
        /// <summary>
        /// Return a helper object to optimize {@link Context} access.
        /// </summary>
        /// <returns></returns>
        public abstract Object getThreadContextHelper();
        /// <summary>
        /// 得到当前线程的相关引用
        /// </summary>
        /// <param name="contextHelper"></param>
        /// <returns></returns>
        public abstract Context getContext(Object contextHelper);

        /// <summary>
        /// 关联上下文与当前线程
        /// </summary>
        /// <param name="contextHelper"></param>
        /// <param name="cx"></param>
        public abstract void setContext(Object contextHelper, Context cx);



        /// <summary>
        /// 返回当前线程的类读取器
        /// Return the ClassLoader instance associated with the current thread.
        /// protected abstract ClassLoader getCurrentThreadClassLoader();
        /// </summary>
        /// <returns></returns>
        public abstract object getCurrentThreadClassLoader();

        /// <summary>
        /// 尝试调用私有类的方法
        /// </summary>
        /// <param name="accessibleObject"></param>
        /// <returns></returns>
        public abstract bool tryToMakeAccessible(Object accessibleObject);

        public static VMBridge instance = makeInstance();
        private static VMBridge makeInstance()
        {
            //    String[] classNames = {
            //    "org.mozilla.javascript.VMBridge_custom",
            //    "org.mozilla.javascript.jdk15.VMBridge_jdk15",
            //    "org.mozilla.javascript.jdk13.VMBridge_jdk13",
            //    "org.mozilla.javascript.jdk11.VMBridge_jdk11",
            //};
            //    for (int i = 0; i != classNames.Length; ++i)
            //    {
            //        String className = classNames[i];
            //        //Class<?> cl = Kit.classOrNull(className);
            //        //if (cl != null) {
            //        //    VMBridge bridge = (VMBridge)Kit.newInstanceOrNull(cl);
            //        //    if (bridge != null) {
            //        //        return bridge;
            //        //    }
            //        //}

            //    }
            //    throw new Exception("Failed to create VMBridge instance");
            try
            {
                return new VMBridge2();
            }
            catch
            {
                throw new Exception("[创建Javascript虚拟机失败]");
            }
        }

        public Object getInterfaceProxyHelper(ContextFactory cf,
                                             Type[] interfaces)
        {
            throw Context.reportRuntimeError(
                "VMBridge.getInterfaceProxyHelper is not supported");
        }

        public Object newInterfaceProxy(Object proxyHelper,
                                       ContextFactory cf,
                                       InterfaceAdapter adapter,
                                       Object target,
                                       Scriptable topScope)
        {
            throw Context.reportRuntimeError(
                "VMBridge.newInterfaceProxy is not supported");
        }

        public abstract bool isVarArgs(MethodBase member);


        public IEnumerator getJavaIterator(Context cx, Scriptable scope, Object obj)
        {
            if (obj is Wrapper)
            {
                Object unwrapped = ((Wrapper)obj).unwrap();
                IEnumerator iterator = null;
                if (unwrapped is IEnumerator)
                    iterator = (IEnumerator)unwrapped;
                return iterator;
            }
            return null;
        }
    }// end for class
}
